import TipsView from '../../view/component/TipsView';
import {$} from '../../config/Config';
import SingleBase from '../base/SingleBase';
export default class UI extends SingleBase {
    private scene: cc.Node;
    private layer_list: cc.Node[] = [];
    private net_loading: cc.Node;
    private is_loading: boolean = false;
    private res = {};
    private prev_scene_url: string;
    getCanvas(): cc.Node {
        return cc.find('Canvas');
    }
    getCurrentScene(): cc.Node {
        return this.getGameSceneRoot().children[0];
    }
    getGameSceneRoot(): cc.Node {
        return cc.find('Canvas/game_scene');
    }
    getGameLayerRoot(): cc.Node {
        return cc.find('Canvas/game_layer');
    }
    getGameLoadingRoot(): cc.Node {
        return cc.find('Canvas/game_loading');
    }
    getPrevSceneUrl(): string {
        return this.prev_scene_url;
    }
    hasLayerItem() {
        return this.layer_list.length > 0;
    }

    showTips(text: any = '', time: number = 150, color?: cc.Color) {
        if (!text) {
            return;
        }
        this.createNode($.Prefab.tips_item).then(node => {
            TipsView.get().show(this.getGameLoadingRoot(), node, text, time, color);
        })
    }

    hideAllTips() {
        TipsView.get().clear();
    }

    showNetLoading(msg: string = '', is_reconnect: boolean = false) {
        if (!this.net_loading) {
            this.createNode($.Prefab.net_loading).then(node => {
                this.net_loading = node;
                this.net_loading.parent = this.getGameLoadingRoot();
                let loading = this.net_loading.getComponent('NetLoading');
                loading.init(msg, is_reconnect);
            });
        } else {
            this.net_loading.show();
            this.net_loading.getComponent('NetLoading').init(msg, is_reconnect);
        }
    }

    hideNetLoading() {
        if (this.net_loading) {
            this.net_loading.hide();
        }
    }

    async getPrefab(url: string): Promise<cc.Prefab> {
        return new Promise((resolve, reject) => {
            cc.resources.load(url, cc.Prefab, (err, res) => {
                if (err) {
                    console.error(url + ' not exist');
                    return;
                }
                resolve(res);
            });
        });
    }

    getPrefabSync(url: string): cc.Prefab {
        let res: cc.Prefab = cc.resources.get(url, cc.Prefab);
        if (!res) {
            console.error(url + '资源未加载');
            return;
        }
        return res;
    }

    getAtlas(url: string): Promise<cc.SpriteAtlas> {
        return new Promise((resolve, reject) => {
            cc.resources.load(url, cc.SpriteAtlas, (err, res) => {
                if (err) {
                    console.error(url + ' not exist');
                    return;
                }
                resolve(res);
            });
        });
    }

    getAtlasSync(url: string): cc.SpriteAtlas {
        let res: cc.SpriteAtlas = cc.resources.get(url, cc.SpriteAtlas);
        if (!res) {
            console.error(url + '资源未加载');
            return;
        }
        return res;
    }

    getTextureSync(url: string): cc.SpriteFrame {
        let res: cc.SpriteFrame  = cc.resources.get(url, cc.SpriteFrame);
        if (!res) {
            console.error(url + '资源未加载');
            return;
        }
        return res;
    }

    addTexture(url: string) {
        cc.resources.load(url, cc.SpriteFrame);
    }

    getTexture(url: string): Promise<cc.SpriteFrame> {
        return new Promise((resolve, reject) => {
            cc.resources.load(url, cc.SpriteFrame, (err, res: cc.SpriteFrame)=> {
                if (err) {
                    console.error(url + ' not exist');
                    return;
                }
                resolve(res);
            });
        });
    }

    geTextAsset(url: string): Promise<cc.TextAsset> {
        return new Promise((resolve, reject) => {
            cc.resources.load(url, cc.TextAsset, (err, res: cc.TextAsset) => {
                if (err) {
                    console.error(url + ' not exist');
                    return;
                }
                resolve(res);
            });
        });
    }

    createNodeSync(url: string): cc.Node {
        let prefab = this.getPrefabSync(url);
        if (prefab) {
            let node = cc.instantiate(prefab);
            return node;
        }
        console.error(url + '资源未加载');
    }
    async createNode(url: string): Promise<cc.Node> {
        return new Promise((resolve, reject) => {
            cc.resources.load(url, cc.Prefab, (err, res: any) => {
                if (err) {
                    console.error(url + ' not exist');
                    return;
                }
                let node = cc.instantiate(res) as cc.Node;
                /*节点重命名*/
                node.name = res.name;
                node.url_name = url;
                node.show();
                resolve(node);
            });
        });
    }
    async addLayer(url: string, is_limit_ctrl: boolean = true): Promise<cc.Node> {
        for (let node of this.layer_list) {
            if (node['url'] === url) {
                console.warn('已存在');
                return;
            }
        }
        if (is_limit_ctrl && this.is_loading) {
            console.warn('已有正在加载...');
            return;
        }
        this.is_loading = true;
        let node = await this.createNode(url);
        node.parent = this.getGameLayerRoot();
        this.layer_list.push(node);
        setTimeout(() => {
            this.is_loading = false;
        }, 100);
        return node;
    }
    removeLayer(target: string | cc.Node) {
        for (let i = 0; i < this.layer_list.length; i++) {
            let node = this.layer_list[i];
            if (node['url'] === target || node === target) {
                node.destroy();
                this.layer_list.splice(i, 1);
                break;
            }
        }
    }
    removeAllLayer() {
        this.layer_list.forEach(value => value.destroy());
        this.layer_list = [];
    }

    async loadScene(url: string): Promise<null> {
        let node = this.getGameLoadingRoot().$('loading');
        node.show();
        node.$('percent').setLabel('0%');
        return new Promise((resolve, reject) => {
            if (this.res[url]) {
                let arr = [5, 18, 25, 29, 40, 45, 60, 80, 90, 100, 100];
                let i = 0;
                const id = setInterval(() => {
                    i++;
                    node.$('percent').setLabel(arr[i] + '%');
                    if (i > 10) {
                        clearInterval(id);
                        node.hide();
                        this.addScene(url);
                        resolve(true);
                    }
                }, 50);
            } else {
                this.loadResDir('./atlas', node.$('percent')).then(value => {
                    this.res[url] = true;
                    node.hide();
                    this.addScene(url);
                    resolve(true);
                });
            }
        })
    }

    reloadScene(url: string) {
        this.removeScene(url);
        this.addScene(url);
    }

    removeScene(url: string) {
        if (this.scene && this.scene.url_name === url) {
            this.scene.destroy();
            this.scene = null;
        }
    }
    async addScene(url: string): Promise<cc.Node> {
        if (this.scene && this.scene.url_name === url) {
            console.warn('已存在');
            return;
        }
        if (this.is_loading) {
            console.warn('已有正在加载...');
            return;
        }
        this.is_loading = true;
        let node = await this.createNode(url);
        node.parent = this.getGameSceneRoot();
        if (this.scene) {
            this.prev_scene_url = this.scene.url_name;
            this.scene.destroy();
            this.scene = null;
        }
        this.scene = node;
        setTimeout(() => {
            this.is_loading = false;
        }, 100);
        return node;
    }

    loadResDir(url: string, loading: cc.ProgressBar | cc.Node): Promise<any[]> {
        console.time(url);
        return new Promise((resolve, reject) => {
            let curr_value = 0;
            cc.resources.loadDir(url, (completedCount: number, totalCount: number, item: any) => {
                let percent = (completedCount / totalCount).toFixed(2).toNumber();
                if (percent > curr_value) {
                    curr_value = percent;
                    if (loading instanceof cc.ProgressBar) {
                        loading.progress = percent;
                    } else if (loading instanceof cc.Node) {
                        loading.setLabel((percent * 100).toFixed(0) + '%');
                    }
                }
            }, (error: Error, assets: Array<any>) => {
                if (error || assets.length === 0) {
                    console.error(url + ' not exist');
                } else {
                    resolve(assets);
                }
                console.timeEnd(url);
            });
        });
    }

    loadResArray(url: string[], loading: cc.ProgressBar | cc.Node) {
        console.time(url.toString());
        return new Promise((resolve, reject) => {
            let curr_value = 0;
            cc.resources.load(url, (completedCount: number, totalCount: number, item: any) => {
                let percent = (completedCount / totalCount).toFixed(2).toNumber();
                if (percent > curr_value) {
                    curr_value = percent;
                    if (loading instanceof cc.ProgressBar) {
                        loading.progress = percent;
                    } else {
                        loading.setLabel((percent * 100).toFixed(0) + '%');
                    }
                }
            }, () => {
                resolve(true);
                console.timeEnd(url.toString());
            });
        });
    }

    loadRes<T>(url: any, type: T): Promise<T> {
        return new Promise((resolve, reject) => {
            cc.resources.load(url, type, (err, res) => {
                if (err) {
                    console.error(url + ' not exist');
                    return;
                }
                resolve(res);
            });
        });

    }
}